#ifndef __CONTROLLER_H__
#define __CONTROLLER_H__

#include <QThread>
#include <QImage>
#include <QDebug>
#include <QThread>
#include <queue>
#include <tuple>
#include <opencv2/opencv.hpp>

#include "video.h"
#ifdef __USE_CUDA_WARD_SENSE__
#include "inference.h"
#include "cuda_manager.h"
#endif

constexpr size_t MAX_STREAM_NUM =       4;
constexpr size_t DETECT_FRAME_STRIDE =  10;

static QImage mat2qimg(const cv::Mat& mat) {
    // 确保图像是 BGR 格式，因为 OpenCV 默认使用 BGR，Qt 使用 RGB
    if (mat.channels() == 3) {
        return QImage((unsigned char*) mat.data, mat.cols, mat.rows, QImage::Format_RGB888).rgbSwapped();
    } else if (mat.channels() == 1) {
        return QImage(mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);
    }

    qWarning() << "Unsupported image format!";
    return QImage();
}

#ifdef __USE_CUDA_WARD_SENSE__
class ModelLoaderThread : public QThread {
    Q_OBJECT

public:
    ModelLoaderThread(QObject *parent = nullptr, DL_INIT_PARAM param = {})
    : QThread(parent), param(param) {}

    DL_INIT_PARAM param;

protected:
    void run() override {
        // 加载模型
        CudaManager::getInstance().loadModel(param);
        emit modelLoaded();  // 加载完成后发出信号
    }

signals:
    void modelLoaded();  // 加载完成信号
};
#endif

class LogicThread : public QThread {
    Q_OBJECT

public:
    LogicThread(QObject* parent = nullptr) : QThread(parent), stopProcessing(false) {}
    ~LogicThread() {
        stop();
        this->quit();
        this->wait();
    }

#ifdef __USE_CUDA_WARD_SENSE__
    std::vector<DL_RESULT> processWithCuda(MatWrapper& mat_wrapper, int counter_id);
    void drawDetectionResults(cv::Mat& mat, const DL_RESULT& result);
#endif
    MatWrapper fetchNextFrame();

    void stop() {
        // QMutexLocker locker(&queue_mutex);
        std::unique_lock<std::mutex> lock(queue_mutex);
        stopProcessing = true;
        pic_cond.notify_all();
    }

protected:
    void run();

signals:
    void frameReady(QImage img, int id);

public:
#ifdef __USE_CUDA_WARD_SENSE__
    std::vector<std::vector<DL_RESULT>> cam_acting_res{MAX_STREAM_NUM};
#endif

private:
    bool stopProcessing;
    int counter[MAX_STREAM_NUM] = { 0 };
};

#endif // __CONTROLLER_H__
